'''
连线
PICO    	DS1302
GPIO2 -----  CLK
GPIO3 -----  DAT
GPIO4 -----  RST

PICO  -----  MAX7219 点阵
GPIO10 -----   CLK
GPIO11 -----   CS
GPIO13 -----   DIN
'''

from machine import Pin,SPI,Timer,ADC


import DS1302 #导入DS1302模块
import MAX7219 #导入MAX7219模块
import time
import random

spi=SPI(1,baudrate=800000,sck=Pin(10), mosi=Pin(11), miso=Pin(12)) # 初始化SPI
ss = Pin(13,Pin.OUT)

adc = ADC(0) # ADC0 通道 IO26
L_Button = Pin(22,Pin.IN) # 左侧按键
R_Button = Pin(7,Pin.IN) # 右侧按键

hour = 0
minute = 0

displayMode = 0

#                    CLK    DAT   RST
ds = DS1302.DS1302(Pin(2),Pin(3),Pin(4)) # 实例化一个DS1302对象

display = MAX7219.Matrix8x8(spi, ss, 4)# 实例化一个点阵模块对象

timer = Timer() # 创建一个定时器

'''
下面是 关于 DS1302 的一些方法
ds.DateTime() # 返回是一个列表包含 年，月，日，星期，时，分，秒
以下返回都是 int 类型
ds.Year() # 不带参数返回年，    带参数设置年
ds.Month()# 不带参数返回月，    带参数设置月
ds.Day()# 不带参数返回日，      带参数设置日
ds.Weekday()# 不带参数返回星期，带参数设置星期
ds.Hour() # 不带参数返回时，    带参数设置时
ds.Minute() # 不带参数返回分，  带参数设置分
ds.Second() # 不带参数返回秒，  带参数设置秒
'''
# 以下是关于点阵模块的 方法
# display.fill(0) # 清屏
# display.text('1234',0,0,1) # 显示字符(字符串)，每位点阵模块显示一位字符
# display.pixel(0,0,0) # 显示具体哪一个像素点参数(x,y,1或0) 1:点亮 0:熄灭
# display.line(0,0,31,4,1) # 画横线 从（x1,y1）→（x2,y2）, 1|0）1:点亮 0:熄灭
# display.hline(0,0,32,1)# 画横线  参数 （x,y,长度,1:点亮 0:熄灭)
# display.vline(2,3,3,1)# 画竖线 参数 （x,y,长度,1:点亮 0:熄灭)
# display.show() # 更新显示，没有此句不会显示

count = 0 # 创建一个全局变量count
last_brigheness = 0;

def map(x,in_min,in_max,out_min,out_max):
    '''
    数值映射
    '''
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min


def timerIsr(timer):
    '''
    定时中断函数
    '''
    global count,last_brigheness
    count = count + 1
    brigheness = adc.read_u16() # 读取ADC数值
    
    if brigheness < 52000 and brigheness > 5505: 
        brigheness = int(map(brigheness,5505,52000,1,15)) # 把数值映射到区间 1-15
        if brigheness != last_brigheness: # 判断数值是否有变化
            last_brigheness = brigheness
            display.brightness(brigheness-1) # 设置点阵屏的亮度
        
    
def setTime(year,month,today,weekday,hour,minute,senond):
    '''
    设置DS1302时间
    参数 年，月，日，星期，时，分，秒
    '''
    ds.Year(year)
    ds.Month(month)
    ds.Day(today)
    ds.Weekday(weekday)
    ds.Hour(hour)
    ds.Minute(minute)
    ds.Second(senond)


def displayTime():
    '''
    点阵显示时间
    '''
    display.fill(0)
    now_time = str(ds.Hour()//10) + str(ds.Hour()%10) + str(ds.Minute()//10) +  str(ds.Minute()%10)  # 从DS1302获取时间分解成每一位再转成字符串
    display.text(now_time,0,0,1)
    display.pixel(16,0,1)
    display.pixel(16,7,1)
    display.show()
    time.sleep(1)
    display.pixel(16,0,0)
    display.pixel(16,7,0)
    display.show()
    time.sleep(1)
 
def displayGif1():
    '''
    显示表情1
    '''
    '''
    display.fill(0)
    display.show()
    display.pixel(2,0,1)
    display.pixel(31-2,0,1)
    display.pixel(3,1,1)
    display.pixel(31-3,1,1)
    display.hline(4,2,3,1)
    display.hline(31-4-2,2,3,1)
    display.pixel(8,0,1)
    display.pixel(31-8,0,1)
    display.pixel(7,1,1)
    display.pixel(31-7,1,1)
    display.hline(15,5,3,1)
    display.pixel(14,6,1)
    display.pixel(31-14+1,6,1)
    display.pixel(13,7,1)
    display.pixel(31-13+1,7,1)
    display.show()
    time.sleep(1)
    '''
    display.fill(0)
    display.show()
    display.hline(0,0,9,1)
    display.hline(23,0,9,1)
    display.vline(1,1,2,1)
    display.vline(2,1,2,1)
    display.vline(24,1,2,1)
    display.vline(25,1,2,1)
    display.hline(13,7,6,1)
    display.show()
    time.sleep(1)
    for j in range(3):
        for i in range(1,7):
            display.vline(i-1,1,2,0)
            display.vline(i+1-1,1,2,0)
            display.vline(i+23-1,1,2,0)
            display.vline(i+24-1,1,2,0)
            display.vline(i,1,2,1)
            display.vline(i+1,1,2,1)
            display.vline(i+23,1,2,1)
            display.vline(i+24,1,2,1)
            display.show()
            time.sleep(0.1)        
        for i in range(6,0,-1):
            display.vline(i+1,1,2,0)
            display.vline(i+1+1,1,2,0)
            display.vline(i+23+1,1,2,0)
            display.vline(i+24+1,1,2,0)
            display.vline(i,1,2,1)
            display.vline(i+1,1,2,1)
            display.vline(i+23,1,2,1)
            display.vline(i+24,1,2,1)
            display.show()
            time.sleep(0.1)
    time.sleep(1)
    display.fill(0)
    display.show()
    display.hline(0,0,9,1)
    display.hline(23,0,9,1)
    display.vline(5,1,2,0)
    display.vline(31-5,1,2,0)
    display.pixel(13,5,1)
    display.pixel(31-13,5,1)
    display.pixel(14,6,1)
    display.pixel(31-14,6,1)
    display.pixel(15,7,1)
    display.pixel(31-15,7,1)
    display.show()
    time.sleep(1)
    display.vline(5,1,2,0)
    display.vline(31-5,1,2,0)
    display.show()
    time.sleep(1)

def displayGif2():
    '''
    显示表情2
    '''
    display.fill(0)
    display.show()
    display.hline(2,0,2,1)
    display.hline(31-2-1,0,2,1)
    display.hline(1,1,4,1)
    display.hline(31-1-3,1,4,1)
    display.hline(1,2,4,1)
    display.hline(31-1-3,2,4,1)
    display.hline(2,3,2,1)
    display.hline(31-2-1,3,2,1)
    display.pixel(13,5,1)
    display.pixel(31-13,5,1)
    display.pixel(14,6,1)
    display.pixel(31-14,6,1)
    display.pixel(15,7,1)
    display.pixel(31-15,7,1)
    display.show()
    time.sleep(2)
    display.fill(0)
    display.show()
    display.pixel(1,0,1)
    display.pixel(31-1,0,1)
    display.pixel(2,1,1)
    display.pixel(31-2,1,1)
    display.pixel(3,2,1)
    display.pixel(31-3,2,1)
    display.pixel(2,3,1)
    display.pixel(31-2,3,1)
    display.pixel(1,4,1)
    display.pixel(31-1,4,1)
    display.pixel(13,5,1)
    display.pixel(31-13,5,1)
    display.pixel(14,6,1)
    display.pixel(31-14,6,1)
    display.pixel(15,7,1)
    display.pixel(31-15,7,1)
    display.show()
    time.sleep(0.2)

def LbuttonIsr(L):
    global displayMode
    time.sleep(0.02) # 软件延时消抖
    if L_Button.value() == 0: #按键按下是低电平
        print("L")
        if displayMode >= 3:
            displayMode = 0
        else:
            displayMode = displayMode+1
    
def RbuttonIsr(R):
    
    time.sleep(0.10) # 软件延时消抖
    if R_Button.value() == 0: #按键按下是低电平
        pass

    
timer.init(freq = 1,mode = Timer.PERIODIC,callback = timerIsr) # 初始化定时器 频率 1秒

L_Button.irq(LbuttonIsr,Pin.IRQ_FALLING) # 设置中断为下降沿触发
R_Button.irq(RbuttonIsr,Pin.IRQ_FALLING) # 设置中断为下降沿触发

def displaySetHour():
    '''
    按键设置小时界面
    '''
    global hour
    display.fill(0) # 清屏点阵
    hour = str(ds.Hour()) # 从DS1302获取小时并转为 str 类型
    while 1:
        hour = str(hour)
        display.fill(0)
        display.text(hour,0,0,1) # 单独显示小时
        display.show()
        hour = int(hour) # 下面要对 hour 做更改，转为 int 类型
        if R_Button.value() == 0: # 如果右键按下
            time.sleep(0.1)    # 延时消抖
            if R_Button.value() == 0: # 再次判断右键按下
                if hour >= 23:   # 小时 上限 23
                    hour = 0
                else:
                    hour += 1 # 更改hour的值
                    print(hour)
        if L_Button.value() == 0: # 如果左键按下
            time.sleep(0.1) # 延时消抖
            if L_Button.value() == 0: # 再次判断左键按下
                print("break")
                ds.Hour(hour) # 向DS1302 写入小时值
                break;  # 跳出循环
    
def displaySetMinute():
    '''
    按键设置分钟界面
    '''
    global minute
    display.fill(0) # 清屏点阵
    minute = str(ds.Minute())# 从DS1302获取分钟并转为 str 类型
    while 1:
        minute = str(minute)
        display.fill(0)
        display.text(minute,15,0,1) # 单独显示分钟
        display.show()
        minute = int(minute) # 下面要对 minute 做更改，转为 int 类型
        if R_Button.value() == 0: # 如果右键按下
            time.sleep(0.1) # 延时消抖
            if R_Button.value() == 0: # 再次判断右键按下
                if minute >= 59: # 小时 上限 59
                    minute = 0
                else:
                    minute += 1  # 更改minute的值
                    
        if L_Button.value() == 0: # 如果左键按下
            time.sleep(0.1) # 延时消抖
            if L_Button.value() == 0: # 再次判断左键按下
                print("break")
                ds.Minute(minute) # 向DS1302 写入分钟值
                break;  # 跳出循环

def displayClock():
    '''
    普通界面
    '''
    global count
    if count > 0 and count <= 20:
        displayTime()
    elif count > 20 and count <=27:
        if random.randint(0,9)%2 == 0:
            displayGif2()
        else:
            displayGif1()
    elif count > 30:
        count = 0


def main():
    global displayMode
    if displayMode == 0:
        displayClock()
    if displayMode == 1:
        displaySetHour()
    if displayMode == 2:
        displaySetMinute()     

if __name__ == "__main__":
    #setTime(2021,10,29,5,15,27,30)
    while 1:
        #print(adc.read_u16())
        main()
        '''
        if count > 0 and count <= 20:
            displayTime()
        elif count > 20 and count <=27:
            if random.randint(0,9)%2 == 0:
                displayGif2()
            else:
                displayGif1()
        elif count > 30:
            count = 0
        '''
